<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>My first three.js app</title>
  <style>
    body { margin: 0; }
  </style>

  <script src="./three.js-r148/build/three.js"></script>
</head>
<body>
  <canvas id="c"></canvas>


  <script>
    function main() {
      const canvas = document.querySelector('#c');

      // 渲染器
      const renderer = new THREE.WebGLRenderer({antialias: true, canvas});

      // 创建摄像机
      const fov = 75;
      const aspect = 2;  // 相机默认值
      const near = 0.1;
      const far = 5;
      const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);

      camera.position.z = 2;

      // 创建场景
      const scene = new THREE.Scene();

      {
        // 加入平行光
        const color = 0xFFFFFF;
        const intensity = 3;
        const light = new THREE.DirectionalLight(color, intensity);
        light.position.set(-1, 2, 4);
        scene.add(light);
      }

      // 创建一个几何体
      const boxWidth = 1;
      const boxHeight = 1;
      const boxDepth = 1;
      const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);

      // 创建材质
      // const material = new THREE.MeshBasicMaterial({color: 0x44aa88});
      const material = new THREE.MeshPhongMaterial({color: 0x44aa88});

      // 创建一个网格
      // const cube = new THREE.Mesh(geometry, material);

      // 创建多个
      const cubes = [
        makeInstance(geometry, 0x44aa88,  0),
        makeInstance(geometry, 0x8844aa, -2),
        makeInstance(geometry, 0xaa8844,  2),
      ];

      // 添加网格
      // scene.add(cube);

      // 将场景和摄像机加入渲染器
      renderer.render(scene, camera);

      // 到这里很难看出来这是一个三维的立方体，因为我们直视Z轴的负方向并且立方体和坐标轴是对齐的，所以我们只能看到一个面。
      // 我们来让立方体旋转起来，以便更好的在三维环境中显示。为了让它动起来我们需要用到一个渲染循环函数
      // requestAnimationFrame.

      function render(time) {
        time *= 0.001;  // 将时间单位变为秒

        cubes.forEach((cube, ndx) => {
          const speed = 1 + ndx * .1;
          const rot = time * speed;
          cube.rotation.x = rot;
          cube.rotation.y = rot;
        });

        renderer.render(scene, camera);

        requestAnimationFrame(render);
      }
      requestAnimationFrame(render);

      function makeInstance(geometry, color, x) {
        const material = new THREE.MeshPhongMaterial({color});

        const cube = new THREE.Mesh(geometry, material);
        scene.add(cube);

        cube.position.x = x;

        return cube;
      }
    }
    main()
  </script>
</body>
</html>
